package datasource.review;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Scanner;
import java.util.StringTokenizer;

import com.aliasi.util.Pair;

public class TextParser {
	private TopicClassifier model = new TopicClassifier();
	private String fileName;
	private ArrayList<ReviewObject> objs = new ArrayList<ReviewObject>();
	private boolean getInput;
	private BufferedWriter bw = null;
	private BufferedWriter outputw = null;
	private String[] labels = { "nothing", "room", "service", "location",
			"parking", "utility", "food" };
	private int numCase = 0;

	TextParser(String fileName, boolean getInput) {
		this.fileName = fileName;
		this.getInput = getInput;
		String dir = "res/train_hotel_files";
		model.train(dir);
		if (getInput) {
			String trainFile = fileName + ".train";
			try {
				bw = new BufferedWriter(new FileWriter(trainFile));

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			String outputFile = fileName + ".result";
			try {
				outputw = new BufferedWriter(new FileWriter(outputFile));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private Date value2date(int month, int day, int year) {
		String[] num = new String[] { "01", "02", "03", "04", "05", "06", "07",
				"08", "09" };

		DateFormat sdf = new SimpleDateFormat("yyyy:MM:dd");
		Date d;
		try {
			d = sdf.parse("" + year + ":"
					+ (month <= 9 ? num[month - 1] : month) + ":"
					+ (day <= 9 ? num[day - 1] : day));
			return d;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private boolean processPara(String para, int objId) {
		ReviewObject obj = new ReviewObject(objId);
		// --------- parse time ------------------
		String[] months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
				"Aug", "Sep", "Oct", "Nov", "Dec" };
		HashMap<String, Integer> monthDict = new HashMap();
		for (int i = 0; i < months.length; i++) {
			monthDict.put(months[i].toLowerCase(), i + 1);
		}
		StringTokenizer st = new StringTokenizer(para, " ");
		boolean hasTime = false;
		if (st.countTokens() >= 3) {
			String month = st.nextToken();
			String day = st.nextToken();
			String year = st.nextToken();
			Integer monthValue = monthDict.get(month.toLowerCase());
			if (monthValue != null) {
				try {
					int dayValue = Integer.parseInt(day);
					int yearValue = Integer.parseInt(year);
					hasTime = true;
					obj.time = value2date(yearValue, monthValue, dayValue);
				} catch (Exception e) {

				}
			}
		}
		// ------------ parse sentences -------------
		String content = para;
		if (hasTime) {
			content = "";
			while (st.hasMoreElements()) {
				content += st.nextToken() + " ";
			}
		}
		try {
			System.out.print("Time: " + (obj.time == null ? "" : obj.time)
					+ "\n");
			outputw.write("Time: " + (obj.time == null ? "" : obj.time) + "\n");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		StringTokenizer st2 = new StringTokenizer(content, ".");
		while (st2.hasMoreTokens()) {
			if (getInput) {
				System.out.print("Case " + numCase + "\t");
				String output = processSentence(st2.nextToken(), true);
				try {
					if (output == null) {
						bw.close();
						return true;
					} else {
						if (!output.isEmpty()) {
							numCase++;
							bw.write(output);
						}

					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				String text = st2.nextToken();
				if (!text.isEmpty()) {
					String sentence = analyzeSentence(text);
					obj.sentences.add(sentence);
					try {
						System.out.print(sentence);
						outputw.write(sentence);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		return false;
	}

	private String classify(String text) {
		ArrayList<Pair<Integer, Double>> labels = model.predict(text);
		String result = "label:";
		for (Pair<Integer, Double> pair : labels) {
			result += pair.a() + "," + pair.b() + " ";
		}
		return result;
	}

	private String analyzeSentence(String text) {
		String labels = classify(text);
//		Pair<Integer, Double> score = SentimentTest.getSentScore(text);
//		
//
//		if (score != null) {
//			return text + "\n" + labels + score.a() + " " + score.b() + "\n";
//		} else {
//			return text + "\n" + labels;
//		}
		return labels;
	}

	private String processSentence(String nextElement, boolean getInput) {
		for (int i = 0; i < labels.length; i++) {
			System.out.print(i + ":" + labels[i] + " ");
		}
		System.out.println("\n" + nextElement);
		boolean done = false;
		ArrayList<Integer> inds = null;
		Scanner scan = new Scanner(System.in);
		while (!done) {
			inds = new ArrayList<Integer>();
			String line = scan.nextLine();
			StringTokenizer st = new StringTokenizer(line, " ");

			try {
				boolean goodInput = true;
				while (st.hasMoreTokens()) {
					int num = Integer.parseInt(st.nextToken());
					if (num == -1) {
						return null;
					}
					if (num >= 0 && num < labels.length) {
						inds.add(num);
					} else {
						goodInput = false;
						break;
					}
				}
				if (goodInput) {
					done = true;
				}
			} catch (Exception e) {

			}
			if (!done) {
				System.out.println("Bad input, please enter again");
			}
		}
		if (inds.size() > 0) {
			String result = nextElement + "\n";

			for (Integer label : inds) {
				result += (label + " ");
			}
			result += "\n";
			return result;
		}
		return "";

	}

	public void parseSegments() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(fileName));
		String line = br.readLine();
		int count = 0;
		while (line != null) {
			if (processPara(line, count++)) {
				break;
			}
			line = br.readLine();
		}
		br.close();
		if (getInput) {
			bw.close();
		} else {
			outputw.close();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String root = "C:\\home\\files\\tweet_project\\datasets\\OpinRankDataset\\hotels\\las-vegas";
		// TextParser parser = new TextParser(root
		// + "\\usa_nevada_las-vegas_bally_s_las_vegas_hotel_casino", true);
		System.out.println(args[0]);
		TextParser parser = new TextParser(args[0], false);
		try {
			parser.parseSegments();
			System.out.println("Total number of cases: " + parser.numCase);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
